// @author U099151W Sun Chenchen
// all functions in this file  are implemented by the author unless specifically indicated
// [TODO] change to a private variable
var PLAYER_VELOCITY = 1; // 2 grid per movement
var STUDENT_VELOCITY = 1;
var PROFESSOR_VELOCITY = 1;
var GUARD_VELOCITY = 3;

var Scene = function() {
    // to enforce singleton
    if ( arguments.callee._singletonInstance )
        return arguments.callee._singletonInstance;
    arguments.callee._singletonInstance = this;

    var _tutorialImageList = [
        {
            name : "control",
            imageSrc : "assets/img/tutorial/control.jpg"
        },
        {
            name : "character",
            imageSrc : "assets/img/tutorial/character.jpg"
        },
        {
            name : "gameplay",
            imageSrc : "assets/img/tutorial/gameplay.jpg"
        },
        {
            name : "mechanics",
            imageSrc : "assets/img/tutorial/mechanics.jpg"
        }
    ];
    var _backgroundList = [
        {
            name : "technoEdge",
            imageSrc : "assets/img/background/technoedgeFIT.png",
            stage : 0
        },
        {
            name : "stairs",
            imageSrc : "assets/img/background/technoedgeFIT.png",
            stage : 1
        }
    ];
    var _obstacleList = [
        {
            name: "chairLeft",
            imageSrc : "assets/img/obstruction/chairLeft/0.png"
        },
        {
            name: "chairRight",
            imageSrc : "assets/img/obstruction/chairRight/0.png"
        },
        {
            name: "table",
            imageSrc : "assets/img/obstruction/table/0.png"
        },
        {
            name: "dustbin",
            imageSrc : "assets/img/obstruction/dustbin/0.png"
        },
        {
            name: "slipperyFloor",
            imageSrc : "assets/img/obstruction/slipperyFloor/0.png"
        },
        {
            name: "vendingMachine",
            imageSrc : "assets/img/obstruction/vendingMachine/0.png"
        }
    ];
    // @author  GAN MEI YAN VICTORIA
    var _characterSpriteList = {
        StudentSprites : {
            stillRight : {
                length : 1,
                src : "assets/img/NPC/student/stillRight"
            },
            stillLeft : {
                length : 1,
                src : "assets/img/NPC/student/stillLeft"
            },
            walkUpRight : {
                length : 10,
                src : "assets/img/NPC/student/walkRight"
            },
            walkUpLeft : {
                length : 10,
                src : "assets/img/NPC/student/walkLeft"
            },
            walkDownRight : {
                length : 10,
                src : "assets/img/NPC/student/walkRight"
            },
            walkDownLeft : {
                length : 10,
                src : "assets/img/NPC/student/walkLeft"
            },
          /*  walkUp : {
                length : 10,
                src : "assets/img/NPC/student/walkRight"
            },
            walkDown : {
                length : 10,
                src : "assets/img/NPC/student/walkRight"
            },*/
            walkRight : {
                length : 10,
                src : "assets/img/NPC/student/walkRight"
            },
            walkLeft : {
                length : 10,
                src : "assets/img/NPC/student/walkLeft"
            },
            jumpRight : {
                length : 13,
                src : "assets/img/NPC/student/jumpRight"
            },
            jumpLeft : {
                length : 13,
                src : "assets/img/NPC/student/jumpLeft"
            },
            punchRight : {
                length : 11,
                critFrame : 7,
                src : "assets/img/NPC/student/punchRight"
            },
            punchLeft : {
                length : 11,
                critFrame : 7,
                src : "assets/img/NPC/student/punchLeft"
            },
            kickHighRight : {
                length : 14,
                critFrame : 8,
                src : "assets/img/NPC/student/kickHighRight"
            },
            kickHighLeft : {
                length : 14,
                critFrame : 8,
                src : "assets/img/NPC/student/kickHighLeft"
            },
            kickMidRight : {
                length : 13,
                critFrame : 8,
                src : "assets/img/NPC/student/kickMidRight"
            },
            kickMidLeft : {
                length : 13,
                critFrame : 8,
                src : "assets/img/NPC/student/kickMidLeft"
            },
            kickLowRight : {
                length : 14,
                critFrame : 8,
                src : "assets/img/NPC/student/kickLowRight"
            },
            kickLowLeft : {
                length : 14,
                critFrame : 8,
                src : "assets/img/NPC/student/kickLowLeft"
            },
            blockRight : {
                length : 15,
                critFrame : 6,
                lastCritFrame : 10,
                src : "assets/img/NPC/student/blockRight"
            },
            blockLeft : {
                length : 15,
                critFrame : 6,
                lastCritFrame : 10,
                src : "assets/img/NPC/student/blockLeft"
            },
            hitTopFrontRight : {
                length : 9,
                src : "assets/img/NPC/student/hitTopFrontRight"
            },
            hitTopFrontLeft : {
                length : 9,
                src : "assets/img/NPC/student/hitTopFrontLeft"
            },
            hitTopBackRight : {
                length : 9,
                src : "assets/img/NPC/student/hitTopBackRight"
            },
            hitTopBackLeft : {
                length : 9,
                src : "assets/img/NPC/student/hitTopBackLeft"
            },
            hitMidFrontRight : {
                length : 9,
                src : "assets/img/NPC/student/hitMidFrontRight"
            },
            hitMidFrontLeft : {
                length : 9,
                src : "assets/img/NPC/student/hitMidFrontLeft"
            },
            hitMidBackRight : {
                length : 9,
                src : "assets/img/NPC/student/hitMidBackRight"
            },
            hitMidBackLeft : {
                length : 9,
                src : "assets/img/NPC/student/hitMidBackLeft"
            },
            hitLowFrontRight : {
                length : 9,
                src : "assets/img/NPC/student/hitLowFrontRight"
            },
            hitLowFrontLeft : {
                length : 9,
                src : "assets/img/NPC/student/hitLowFrontLeft"
            },
            hitLowBackRight : {
                length : 9,
                src : "assets/img/NPC/student/hitLowBackRight"
            },
            hitLowBackLeft : {
                length : 9,
                src : "assets/img/NPC/student/hitLowBackLeft"
            },
            deathRight : {
                length : 10,
                src : "assets/img/NPC/student/deathRight"
            },
            deathLeft : {
                length : 10,
                src : "assets/img/NPC/student/deathLeft"
            }
        },
        ProfessorSprites : {
            stillRight : {
                length : 1,
                src : "assets/img/NPC/professor/stillRight"
            },
            stillLeft : {
                length : 1,
                src : "assets/img/NPC/professor/stillLeft"
            },
            walkUpRight : {
                length : 10,
                src : "assets/img/NPC/professor/walkRight"
            },
            walkUpLeft : {
                length : 10,
                src : "assets/img/NPC/professor/walkLeft"
            },
            walkDownRight : {
                length : 10,
                src : "assets/img/NPC/professor/walkRight"
            },
            walkDownLeft : {
                length : 10,
                src : "assets/img/NPC/professor/walkLeft"
            },
            walkUp : {
                length : 10,
                src : "assets/img/NPC/professor/walkRight"
            },
            walkDown : {
                length : 10,
                src : "assets/img/NPC/professor/walkRight"
            },
            walkRight : {
                length : 10,
                src : "assets/img/NPC/professor/walkRight"
            },
            walkLeft : {
                length : 10,
                src : "assets/img/NPC/professor/walkLeft"
            },
            talkRight : {
                length : 10,
                critFrame : 6,
                src : "assets/img/NPC/professor/talkRight"
            },
            talkLeft : {
                length : 10,
                critFrame : 6,
                src : "assets/img/NPC/professor/talkLeft"
            },
            hitTopFrontRight : {
                length : 9,
                src : "assets/img/NPC/professor/hitTopFrontRight"
            },
            hitTopFrontLeft : {
                length : 9,
                src : "assets/img/NPC/professor/hitTopFrontLeft"
            },
            hitTopBackRight : {
                length : 9,
                src : "assets/img/NPC/professor/hitTopBackRight"
            },
            hitTopBackLeft : {
                length : 9,
                src : "assets/img/NPC/professor/hitTopBackLeft"
            },
            hitMidFrontRight : {
                length : 9,
                src : "assets/img/NPC/professor/hitMidFrontRight"
            },
            hitMidFrontLeft : {
                length : 9,
                src : "assets/img/NPC/professor/hitMidFrontLeft"
            },
            hitMidBackRight : {
                length : 9,
                src : "assets/img/NPC/professor/hitMidBackRight"
            },
            hitMidBackLeft : {
                length : 9,
                src : "assets/img/NPC/professor/hitMidBackLeft"
            },
            hitLowFrontRight : {
                length : 9,
                src : "assets/img/NPC/professor/hitLowFrontRight"
            },
            hitLowFrontLeft : {
                length : 9,
                src : "assets/img/NPC/professor/hitLowFrontLeft"
            },
            hitLowBackRight : {
                length : 9,
                src : "assets/img/NPC/professor/hitLowBackRight"
            },
            hitLowBackLeft : {
                length : 9,
                src : "assets/img/NPC/professor/hitLowBackLeft"
            },
            deathRight : {
                length : 10,
                src : "assets/img/NPC/professor/deathRight"
            },
            deathLeft : {
                length : 10,
                src : "assets/img/NPC/professor/deathLeft"
            }
        },
        GuardSprites : {
            stillRight : {
                length : 1,
                src : "assets/img/NPC/guard/stillRight"
            },
            stillLeft : {
                length : 1,
                src : "assets/img/NPC/guard/stillLeft"
            },
            runUpRight : {
                length : 8,
                src : "assets/img/NPC/guard/runRight"
            },
            runUpLeft : {
                length : 8,
                src : "assets/img/NPC/guard/runLeft"
            },
            runDownRight : {
                length : 8,
                src : "assets/img/NPC/guard/runRight"
            },
            runDownLeft : {
                length : 8,
                src : "assets/img/NPC/guard/runLeft"
            },
            runRight : {
                length : 8,
                src : "assets/img/NPC/guard/runRight"
            },
            runLeft : {
                length : 8,
                src : "assets/img/NPC/guard/runLeft"
            },
            hitTopFrontRight : {
                length : 9,
                src : "assets/img/NPC/guard/hitTopFrontRight"
            },
            hitTopFrontLeft : {
                length : 9,
                src : "assets/img/NPC/guard/hitTopFrontLeft"
            },
            hitTopBackRight : {
                length : 9,
                src : "assets/img/NPC/guard/hitTopBackRight"
            },
            hitTopBackLeft : {
                length : 9,
                src : "assets/img/NPC/guard/hitTopBackLeft"
            },
            hitMidFrontRight : {
                length : 9,
                src : "assets/img/NPC/guard/hitMidFrontRight"
            },
            hitMidFrontLeft : {
                length : 9,
                src : "assets/img/NPC/guard/hitMidFrontLeft"
            },
            hitMidBackRight : {
                length : 9,
                src : "assets/img/NPC/guard/hitMidBackRight"
            },
            hitMidBackLeft : {
                length : 9,
                src : "assets/img/NPC/guard/hitMidBackLeft"
            },
            hitLowFrontRight : {
                length : 9,
                src : "assets/img/NPC/guard/hitLowFrontRight"
            },
            hitLowFrontLeft : {
                length : 9,
                src : "assets/img/NPC/guard/hitLowFrontLeft"
            },
            hitLowBackRight : {
                length : 9,
                src : "assets/img/NPC/guard/hitLowBackRight"
            },
            hitLowBackLeft : {
                length : 9,
                src : "assets/img/NPC/guard/hitLowBackLeft"
            },
            deathRight : {
                length : 10,
                src : "assets/img/NPC/guard/deathRight"
            },
            deathLeft : {
                length : 10,
                src : "assets/img/NPC/guard/deathLeft"
            }
        },
        PlayerSprites : {
            stillRight : {
                length : 8,
                src : "assets/img/player/stillRight"
            },
            stillLeft : {
                length : 8,
                src : "assets/img/player/stillLeft"
            },
            /*walkUp : {
             length : 10,
             src : "assets/img/player/walkRight"
             },
             walkDown : {
             length : 10,
             src : "assets/img/player/walkRight"
             },*/
            walkUpRight : {
                length : 8,
                src : "assets/img/player/walkRight"
            },
            walkUpLeft : {
                length : 8,
                src : "assets/img/player/walkLeft"
            },
            walkDownRight : {
                length : 8,
                src : "assets/img/player/walkRight"
            },
            walkDownLeft : {
                length : 8,
                src : "assets/img/player/walkLeft"
            },
            walkRight : {
                length : 8,
                src : "assets/img/player/walkRight"
            },
            walkLeft : {
                length : 8,
                src : "assets/img/player/walkLeft"
            },
            jumpRight : {
                length : 14,
                src : "assets/img/player/jumpRight"
            },
            jumpLeft : {
                length : 14,
                src : "assets/img/player/jumpLeft"
            },
            punchRight : {
                length : 11,
                critFrame : 7,
                src : "assets/img/player/punchRight"
            },
            punchLeft : {
                length : 11,
                critFrame : 7,
                src : "assets/img/player/punchLeft"
            },
            kickHighRight : {
                length : 14,
                critFrame : 8,
                src : "assets/img/player/kickHighRight"
            },
            kickHighLeft : {
                length : 14,
                critFrame : 8,
                src : "assets/img/player/kickHighLeft"
            },
            kickMidRight : {
                length : 13,
                critFrame : 8,
                src : "assets/img/player/kickMidRight"
            },
            kickMidLeft : {
                length : 13,
                critFrame : 8,
                src : "assets/img/player/kickMidLeft"
            },
            kickLowRight : {
                length : 14,
                critFrame : 8,
                src : "assets/img/player/kickLowRight"
            },
            kickLowLeft : {
                length : 14,
                critFrame : 8,
                src : "assets/img/player/kickLowLeft"
            },
            specialRight : {
                length : 24,
                critFrame : 6,
                critFrame1 : 12,
                critFrame2 : 18,
                src : "assets/img/player/specialRight"
            },
            specialLeft : {
                length : 24,
                critFrame : 8,
                critFrame1 : 12,
                critFrame2 : 18,
                src : "assets/img/player/specialLeft"
            },
            blockRight : {
                length : 15,
                critFrame : 6,
                lastCritFrame : 10,
                src : "assets/img/player/blockRight"
            },
            blockLeft : {
                length : 15,
                critFrame : 6,
                lastCritFrame : 10,
                src : "assets/img/player/blockLeft"
            },
            hitTopFrontRight : {
                length : 9,
                src : "assets/img/player/hitTopFrontRight"
            },
            hitTopFrontLeft : {
                length : 9,
                src : "assets/img/player/hitTopFrontLeft"
            },
            hitTopBackRight : {
                length : 9,
                src : "assets/img/player/hitTopBackRight"
            },
            hitTopBackLeft : {
                length : 9,
                src : "assets/img/player/hitTopBackLeft"
            },
            hitMidFrontRight : {
                length : 9,
                src : "assets/img/player/hitMidFrontRight"
            },
            hitMidFrontLeft : {
                length : 9,
                src : "assets/img/player/hitMidFrontLeft"
            },
            hitMidBackRight : {
                length : 9,
                src : "assets/img/player/hitMidBackRight"
            },
            hitMidBackLeft : {
                length : 9,
                src : "assets/img/player/hitMidBackLeft"
            },
            hitLowFrontRight : {
                length : 9,
                src : "assets/img/player/hitLowFrontRight"
            },
            hitLowFrontLeft : {
                length : 9,
                src : "assets/img/player/hitLowFrontLeft"
            },
            hitLowBackRight : {
                length : 9,
                src : "assets/img/player/hitLowBackRight"
            },
            hitLowBackLeft : {
                length : 9,
                src : "assets/img/player/hitLowBackLeft"
            },
            sleepRight : {
                length : 16,
                src : "assets/img/player/sleepRight"
            },
            sleepLeft : {
                length : 16,
                src : "assets/img/player/sleepLeft"
            },
            deathRight : {
                length : 18,
                src : "assets/img/player/deathRight"
            },
            deathLeft : {
                length : 18,
                src : "assets/img/player/deathLeft"
            }
        }
    };

    this.getBackgroundList = function() {return _backgroundList;};
    this.getCharacterSpriteList = function() {return _characterSpriteList;};
    this.getObstacleList = function() { return _obstacleList;};
    this.getTutorialImageList = function() { return _tutorialImageList;};
}
var sceneDef = new Scene();

Scene.prototype.Player = function(id, name, x, y, state) {

    this.id = id;
    this.name = name;
    this.x = x;
    this.y = y;
    this.tileX = Math.floor(x/TILE_RESOLUTION);
    this.tileY = Math.floor(y/TILE_RESOLUTION);

    this.widthInGrid = 4;
    this.heightInGrid = 4;

    this.slowedDown = 1;

    if (state === undefined)
        state = "still";
    this.state = state;
    this.nextState = state;

    this.foodCount = 100;
    this.foodMax = 100;
    this.foodDecreaseSpeed = 100 * _inverseFPS / 40;
    this.comboCount = 20;
    this.comboMax = 20;
    this.sprites = sceneDef.getCharacterSpriteList()["PlayerSprites"];
    this.currentSpriteFrame = 0;
}

Scene.prototype.Player.prototype.addFood = function(foodAmount) {
    var food = this.foodCount + foodAmount;
    if (food >= this.foodMax)
        this.foodCount = this.foodMax;
    else
        this.foodCount = food;
}

Scene.prototype.Player.prototype.decreaseFood = function() {
    var food = this.foodCount - this.foodDecreaseSpeed;
    if (food <= 0)
        this.foodCount = 0;
    else
        this.foodCount = food;
}

Scene.prototype.Player.prototype.addCombo = function() {
    var combo = this.comboCount + 0.5;
    if (combo >= this.comboMax)
        this.comboCount = this.comboMax;
    else
        this.comboCount = combo;
}

Scene.prototype.Player.prototype.decreaseCombo = function(amount) {
    var combo = this.comboCount - amount;
    if (combo <= 0)
        this.comboCount = 0;
    else
        this.comboCount = combo;
}


Scene.prototype.Player.prototype.clearGrid = function() {
    for (var i=0; i<1; i++) {
        for (var j=0; j<1; j++) {
            TILE_MAP.GRIDS[this.tileY+j][this.tileX+i]= 0;
        }
    }
}

Scene.prototype.Player.prototype.updateGrid = function() {
    for (var i=0; i<1; i++) {
        for (var j=0; j<1; j++) {
            TILE_MAP.GRIDS[this.tileY+j][this.tileX+i] = 1;
        }
    }
}

Scene.prototype.Player.prototype.moveLeft = function() {
    this.clearGrid();
    var x = this.x - this.slowedDown * PLAYER_VELOCITY * TILE_RESOLUTION / this.sprites[this.state].length;
    var tileX = Math.floor(x/TILE_RESOLUTION);
    if (tileX < 0)
        return;
    this.x = x;
    this.tileX = tileX;
    this.updateGrid();
}

Scene.prototype.Player.prototype.moveRight = function() {
    this.clearGrid();
    var x = this.x + this.slowedDown * PLAYER_VELOCITY * TILE_RESOLUTION / this.sprites[this.state].length;
    var tileX = Math.floor(x/TILE_RESOLUTION);
    if (tileX > TILE_MAP.COLS-1)
        return;
    this.x = x;
    this.tileX = tileX;
    this.updateGrid();
}
Scene.prototype.Player.prototype.moveUp = function() {
    this.clearGrid();
    var y = this.y - this.slowedDown * PLAYER_VELOCITY * TILE_RESOLUTION / this.sprites[this.state].length;
    var tileY = Math.floor(y/TILE_RESOLUTION);
    if (tileY < 1)
        return;
    this.y = y;
    this.tileY = tileY;
    this.updateGrid();
}
Scene.prototype.Player.prototype.moveDown = function() {
    this.clearGrid();
    var y = this.y + this.slowedDown * PLAYER_VELOCITY * TILE_RESOLUTION / this.sprites[this.state].length;
    var tileY = Math.floor(y/TILE_RESOLUTION);
    if (tileY >  TILE_MAP.ROWS-2)
        return;
    this.y = y;
    this.tileY = tileY;
    this.updateGrid();
}
/*Scene.prototype.Player.prototype.moveDiagonalRightUp = function() {
    this.y = this.y + PLAYER_VELOCITY;
    this.x = this.x + PLAYER_VELOCITY;
    this.tileX = Math.floor(this.x/TILE_RESOLUTION);
    this.tileY = Math.floor(this.y/TILE_RESOLUTION);
}*/

Scene.prototype.Player.prototype.updateState = function(state) {
    //this.currentSpriteFrame = 0;
    this.currentSpriteFrame = 0;
    this.state = state;
}

Scene.prototype.Player.prototype.draw = function(context, imageLib) {

    var image = imageLib.getItem('Player_' + this.state+(this.currentSpriteFrame%this.sprites[this.state].length) );
    context.save();
    context.translate(this.x, this.y);
    context.translate(- Math.floor(TILE_RESOLUTION * this.widthInGrid/2), - Math.floor(TILE_RESOLUTION * this.widthInGrid/2));

    if (DEBUG_MODE) {
        context.fillStyle = "red";
        context.fillRect(TILE_RESOLUTION, 0, TILE_RESOLUTION * this.widthInGrid/2, TILE_RESOLUTION * this.heightInGrid);
    } else {
        context.drawImage(image, 0, 0, TILE_RESOLUTION * this.widthInGrid, TILE_RESOLUTION * this.heightInGrid);
    }

    context.restore();
    this.currentSpriteFrame = (this.currentSpriteFrame+1)%this.sprites[this.state].length;
}

Scene.prototype.NPC = function(id, name, x, y, state) {
    this.id = id;
    this.state = state;
    this.name = name;
    this.x = x;
    this.y = y;
    this.tileX = Math.floor(x/TILE_RESOLUTION);
    this.tileY = Math.floor(y/TILE_RESOLUTION);
    this.path = []; // path to the player

    if (state === undefined)
        state = "still";
    this.state = state;

    this.healthMax = 100;
    this.health = 100;
    this.score = 0;

    this.sprites = sceneDef.getCharacterSpriteList()[name+'Sprites'];
    this.currentSpriteFrame = 0;

}

Scene.prototype.NPC.prototype.updateState = function(state) {
    //this.currentSpriteFrame = 0;
    this.state = state;
}

Scene.prototype.NPC.prototype.draw = function(context, imageLib) {
    var image = imageLib.getItem(this.name + '_' + this.state+(this.currentSpriteFrame%this.sprites[this.state].length) );
    context.save();
    context.translate(this.x, this.y);
    context.translate(-image.width/2, -image.height);
    context.drawImage(image, 0, 0);
    context.restore();
    this.currentSpriteFrame++;


}

Scene.prototype.Student =function(id, name, x, y, state, ai, fightSystemIndex) {
    this.id = id;
    this.name = name;
    this.x = x;
    this.y = y;
    this.tileX = Math.floor(x/TILE_RESOLUTION);
    this.tileY = Math.floor(y/TILE_RESOLUTION);
    this.path = []; // path to the player
    this.currentPathNodeIndex = 0;
    this.moveCount = 0;
    this.destination = [this.tileX, this.tileY];
    this.speed = 1;
    this.slowedDown = 1;

    this.widthInGrid = 4;
    this.heightInGrid = 4;

    this.AI_type = ai;
    if (ai === "aggressive") {
        this.radius = 0;
        this.center = [this.tileX, this.tileY];
        this.waitforNextPath = false;
        this.lastEndTime = Date.now();
    }
      if (ai === "corner") {
        this.cornerIndex = 0;
        this.radius = 0;
        this.center = [this.tileX, this.tileY];
        this.waitforNextPath = false;
        this.lastEndTime = Date.now();
    }
    if (ai === "passive") {
        this.inEscape = false;
        this.currentEscapeStart = Date.now();
        this.accumEscapeTime = 0;
        this.EscapeTimeMax = 2500;
    }
    // 0 means normal, 1 means strong
    this.fightSystemIndex = fightSystemIndex;

    this.foodAmount = 5;

    if (state === undefined)
        state = "still";
    this.state = state;
    this.healthMax = 100;
    this.health = 100;
    this.alive = true;
    this.sprites = sceneDef.getCharacterSpriteList()["StudentSprites"];
    this.currentSpriteFrame = 0;
}

Scene.prototype.Student.prototype.updateState = function(state) {
    //this.currentSpriteFrame = 0;
    this.state = state;
}

Scene.prototype.Student.prototype.clearGrid = function() {
    for (var i=0; i<2; i++) {
        for (var j=0; j<2; j++) {
            TILE_MAP.GRIDS[this.tileY+j][this.tileX+i]= 0;
        }
    }
}

Scene.prototype.Student.prototype.updateGrid = function() {
    for (var i=0; i<2; i++) {
        for (var j=0; j<2; j++) {
            TILE_MAP.GRIDS[this.tileY+j][this.tileX+i] = 1;
        }
    }
}

Scene.prototype.Student.prototype.moveLeft = function() {

    var x = this.x - this.slowedDown * STUDENT_VELOCITY * TILE_RESOLUTION / this.sprites[this.state].length;
    var tileX = Math.floor(x/TILE_RESOLUTION);
    if (tileX < 0)
        return;
    this.x = x;
    this.tileX = tileX;

}

Scene.prototype.Student.prototype.moveRight = function() {
    var x = this.x + this.slowedDown * STUDENT_VELOCITY * TILE_RESOLUTION / this.sprites[this.state].length;
    var tileX = Math.floor(x/TILE_RESOLUTION);
    if (tileX > TILE_MAP.COLS-1)
        return;
    this.x = x;
    this.tileX = tileX;
}
Scene.prototype.Student.prototype.moveUp = function() {
    var y = this.y - this.slowedDown * STUDENT_VELOCITY * TILE_RESOLUTION / this.sprites[this.state].length;
    var tileY = Math.floor(y/TILE_RESOLUTION);
    if (tileY < 0)
        return;
    this.y = y;
    this.tileY = tileY;
}
Scene.prototype.Student.prototype.moveDown = function() {
    var y = this.y + this.slowedDown * STUDENT_VELOCITY * TILE_RESOLUTION / this.sprites[this.state].length;
    var tileY = Math.floor(y/TILE_RESOLUTION);
    if (tileY >  TILE_MAP.ROWS-1)
        return;
    this.y = y;
    this.tileY = tileY;
}

Scene.prototype.Student.prototype.draw = function(context, imageLib) {
    var image = imageLib.getItem('Student_' + this.state+(this.currentSpriteFrame%this.sprites[this.state].length) );
    context.save();
    context.translate(this.x, this.y);
    context.translate(- Math.floor(TILE_RESOLUTION * this.widthInGrid/2), - Math.floor(TILE_RESOLUTION * this.widthInGrid/2));
    if (DEBUG_MODE) {
        context.fillStyle = "blue";
        context.fillRect(TILE_RESOLUTION, 0, TILE_RESOLUTION * this.widthInGrid/2, TILE_RESOLUTION * this.heightInGrid);
        context.fillStyle = "black";
        context.font = "15px Arial Black";
        context.fillText(this.AI_type, 0, 0);
        if (this.fightSystemIndex === 0)
            context.fillText("strong", 0, 20);
        else
            context.fillText("weak", 0, 20);
    } else {
        context.drawImage(image, 0, 0, TILE_RESOLUTION * this.widthInGrid, TILE_RESOLUTION * this.heightInGrid);
    }
    context.restore();
    this.currentSpriteFrame = (this.currentSpriteFrame+1)%this.sprites[this.state].length;
}

Scene.prototype.Stage = function(timeStart, timeMax, index) {
    this.timeStart = timeStart;
    this.timeMax = timeMax;
    this.timeLeft = timeMax;
    this.index = index;
}

Scene.prototype.Stage.prototype.decreaseTime = function() {
    var timeElapsed = Date.now() - this.timeStart;
    var timeLeft = this.timeMax - timeElapsed;
    if (timeLeft <= 0)
        this.timeLeft = 0;
    else
        this.timeLeft = timeLeft;
}


Scene.prototype.Professor = function(id, name, x, y, state) {
    this.id = id;
    this.name = name;
    this.x = x;
    this.y = y;
    this.tileX = Math.floor(x/TILE_RESOLUTION);
    this.tileY = Math.floor(y/TILE_RESOLUTION);
    this.path = []; // path to the player
    this.currentPathNodeIndex = 0;
    this.moveCount = 0;
    this.destination = [this.tileX, this.tileY];
    this.speed = 1;

    this.widthInGrid = 4;
    this.heightInGrid = 4;

    this.foodAmount = 10;

    this.effectRadius = 8;
    this.studentSlowedDown = 1;
    this.playerSlowedDown = 0.5;

    if (state === undefined)
        state = "stillRight";
    this.state = state;
    this.healthMax = 200;
    this.health = 200;
    this.alive = true;
    this.sprites = sceneDef.getCharacterSpriteList()["ProfessorSprites"];
    this.currentSpriteFrame = 0;

}

Scene.prototype.Professor.prototype.draw = function(context, imageLib) {
    var image = imageLib.getItem('Professor_' + this.state+(this.currentSpriteFrame%this.sprites[this.state].length) );

    context.save();
    if (this.state.indexOf("talk") !== -1) {
        var ratio = this.currentSpriteFrame / this.sprites[this.state].length;
        context.beginPath();
        context.arc(this.x, this.y, ratio * this.effectRadius * TILE_RESOLUTION, 0, 2 * Math.PI, false);
        context.lineWidth = 5;
        context.strokeStyle = '#003300';
        context.stroke();
    }

    context.translate(this.x, this.y);
    context.translate(- Math.floor(TILE_RESOLUTION * this.widthInGrid/2), - Math.floor(TILE_RESOLUTION * this.widthInGrid/2));
    context.drawImage(image, 0, 0, TILE_RESOLUTION * this.widthInGrid, TILE_RESOLUTION * this.heightInGrid);


    if (DEBUG_MODE) {
        context.lineWidth = 5;
        context.strokeStyle = "blue";
        context.strokeRect(0, 0, TILE_RESOLUTION * this.widthInGrid, TILE_RESOLUTION * this.heightInGrid);
    }
    context.restore();
    this.currentSpriteFrame = (this.currentSpriteFrame+1)%this.sprites[this.state].length;
}


Scene.prototype.Professor.prototype.moveLeft = function() {
    var x = this.x -  PROFESSOR_VELOCITY * TILE_RESOLUTION / this.sprites[this.state].length;
    var tileX = Math.floor(x/TILE_RESOLUTION);
    if (tileX < 0)
        return;
    this.x = x;
    this.tileX = tileX;

}

Scene.prototype.Professor.prototype.moveRight = function() {
    var x = this.x + PROFESSOR_VELOCITY * TILE_RESOLUTION / this.sprites[this.state].length;
    var tileX = Math.floor(x/TILE_RESOLUTION);
    if (tileX > TILE_MAP.COLS-1)
        return;
    this.x = x;
    this.tileX = tileX;
}
Scene.prototype.Professor.prototype.moveUp = function() {
    var y = this.y - PROFESSOR_VELOCITY * TILE_RESOLUTION / this.sprites[this.state].length;
    var tileY = Math.floor(y/TILE_RESOLUTION);
    if (tileY < 0)
        return;
    this.y = y;
    this.tileY = tileY;
}

Scene.prototype.Professor.prototype.moveDown = function() {
    var y = this.y + PROFESSOR_VELOCITY * TILE_RESOLUTION / this.sprites[this.state].length;
    var tileY = Math.floor(y/TILE_RESOLUTION);
    if (tileY >  TILE_MAP.ROWS-1)
        return;
    this.y = y;
    this.tileY = tileY;
}


Scene.prototype.Professor.prototype.updateState = function(state) {
    //this.currentSpriteFrame = 0;
    this.state = state;
}

// campus security
Scene.prototype.Guard = function(id, name, x, y, state) {
    this.id = id;
    this.name = name;
    this.x = x;
    this.y = y;
    this.tileX = Math.floor(x/TILE_RESOLUTION);
    this.tileY = Math.floor(y/TILE_RESOLUTION);
    this.path = []; // path to the player
    this.currentPathNodeIndex = 0;
    this.moveCount = 0;
    this.destination = [this.tileX, this.tileY];
    this.speed = 1;

    this.widthInGrid = 4;
    this.heightInGrid = 4;

    this.foodAmount = 10;

    if (state === undefined)
        state = "stillRight";
    this.state = state;
    this.healthMax = 500;
    this.health = 500;
    this.alive = true;
    this.sprites = sceneDef.getCharacterSpriteList()["GuardSprites"];
    this.currentSpriteFrame = 0;

}

Scene.prototype.Guard.prototype.draw = function(context, imageLib) {
    var image = imageLib.getItem('Guard_' + this.state+(this.currentSpriteFrame%this.sprites[this.state].length) );

    context.save();

    context.translate(this.x, this.y);
    context.translate(- Math.floor(TILE_RESOLUTION * this.widthInGrid/2), - Math.floor(TILE_RESOLUTION * this.widthInGrid/2));
    context.drawImage(image, 0, 0, TILE_RESOLUTION * this.widthInGrid, TILE_RESOLUTION * this.heightInGrid);


    if (DEBUG_MODE) {
        context.lineWidth = 5;
        context.strokeStyle = "blue";
        context.strokeRect(0, 0, TILE_RESOLUTION * this.widthInGrid, TILE_RESOLUTION * this.heightInGrid);
    }
    context.restore();
    this.currentSpriteFrame = (this.currentSpriteFrame+1)%this.sprites[this.state].length;
}


Scene.prototype.Guard.prototype.moveLeft = function() {
    var x = this.x -  GUARD_VELOCITY * TILE_RESOLUTION / this.sprites[this.state].length;
    var tileX = Math.floor(x/TILE_RESOLUTION);
    if (tileX < 0)
        return;
    this.x = x;
    this.tileX = tileX;

}

Scene.prototype.Guard.prototype.moveRight = function() {
    var x = this.x + GUARD_VELOCITY * TILE_RESOLUTION / this.sprites[this.state].length;
    var tileX = Math.floor(x/TILE_RESOLUTION);
    if (tileX > TILE_MAP.COLS-1)
        return;
    this.x = x;
    this.tileX = tileX;
}
Scene.prototype.Guard.prototype.moveUp = function() {
    var y = this.y - GUARD_VELOCITY * TILE_RESOLUTION / this.sprites[this.state].length;
    var tileY = Math.floor(y/TILE_RESOLUTION);
    if (tileY < 0)
        return;
    this.y = y;
    this.tileY = tileY;
}

Scene.prototype.Guard.prototype.moveDown = function() {
    var y = this.y + GUARD_VELOCITY * TILE_RESOLUTION / this.sprites[this.state].length;
    var tileY = Math.floor(y/TILE_RESOLUTION);
    if (tileY >  TILE_MAP.ROWS-1)
        return;
    this.y = y;
    this.tileY = tileY;
}

Scene.prototype.Guard.prototype.updateState = function(state) {
    //this.currentSpriteFrame = 0;
    this.state = state;
}

